詳解 Objective-C 2.0 第 3 版
#Objective-C #書籍
https://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B00GJGOPDW&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=kazaguruma-22&language=ja_JP&ext=.jpg
Amazon : https://amzn.to/35arLRA
感想 nobuoka.icon
今更 Objective-C の本を読む人はそんなに多くはないとは思うが、Objective-C と macOS や iOS などのプラットフォームでの開発について学ぶには良い本だった
古い本ではあるので、最新の情報は別途キャッチアップが必要だが、逆に古い時代のことを学ぶには良い
読書メモ
1 章 : オブジェクトに基づくソフトウェアの作成
手続き型言語によるプログラムは保守性が低く、オブジェクト指向が注目されるようになった
抽象化
Objective-C では、他のオブジェクトを参照するための変数をアウトレット (outlet) と呼ぶことがある
Cocoa と Objective-C の歴史
オブジェクト指向分析・設計では UML などが用いられる
保守性や信頼性を高めるために、独立性の高いモジュールを定義すべき
外部に見せる情報を最小限にし、実現方法を隠蔽する → 情報隠蔽あるいはカプセル化
クラスもモジュールであり、クラスの外部に公開される情報はクラスのインターフェイスと呼ばれる
多くのオブジェクト指向言語は、メッセージによる通信を手続き呼び出しと同じ仕組みで実現 (呼び出し側が待たされる)
Objective-C では、効率的なプロセス間通信のために処理が終わっても返答を返す必要のないメッセージを宣言できる
C 言語の規格
Mac OS X で提供されるコンパイラは、もともと gcc であったが、Xcode 4.2 以降は LLVM の Clang になった
2 章 : Objective-C のプログラム
メッセージ式 : [obj msg]
@interface や @class などは Objective-C で導入されたコンパイラ指示子
本書では Cocoa と Cocoa Touch の環境を合わせて Cocoa 環境と呼ぶ
Cocoa 環境では、システムが提供するクラスや関数は Framework という、構造を持った動的なライブラリとして提供
3 章 : 継承とクラス
Cocoa 環境には、NSObject というルートクラスがある
他のルートクラスとしては NSProxy
全てのクラスはルートクラスを継承しなければオブジェクトとして振る舞うことができない
4 章 : オブジェクトの型と動的結合
Objective-C におけるメッセージは動的結合 (dynamic binding) = 実行時に初めて処理できるかどうかわかる
これによりポリモーフィズムが実現
インスタンス変数は基本的にそのクラス自身か子クラスからしか参照できない
nobuoka.icon そうだったんだ。 インターフェイス宣言に書けば外から参照可能なのだと思ってた
可視性を変更するためのコンパイラ指示子がある
Xcode 4.2 以降の Clang であればインスタンス変数の宣言を実装部に書けるように
オブジェクト指向の言語におけるクラスの捉え方は 2 種類
クラスは静的な定義であってプログラムの実行時に実体としては存在しないよ派
クラスもひとつのオブジェクトだよ派 (Objective-C はこちら) → クラスオブジェクト
Objective-C では、クラスオブジェクトをファクトリと呼び、クラスメソッドのことをファクトリメソッドと呼ぶこともある
nobuoka.icon メソッドの使い方によってファクトリメソッドになることもある、というのが正しそう??
Objective-C におけるクラス
クラスオブジェクトの型は Class
Class 型のための空ポインタ : Nil
クラス変数を定義する構文はないが、実装部で static 指定子をつけて宣言した変数をクラス変数だとみなせる
クラスの初期化は initialize メソッドで行える
5 章 : リファレンスカウンタを用いたメモリ管理方式
Cocoa 環境の Objective-C ではリファレンスカウンタを用いた動的なメモリ管理
ARC という自動的なカウンタ管理方式
Objective-C 2.0 からはガベージコレクションも
インスタンスの自動解放 (autorelease) の仕組みがある
一時的に利用するオブジェクトを後から自動で解放する
Objective-C では、一時的なオブジェクト (自動解放プールに登録されているもの) を生成するコンストラクタをコンビニエンスコンストラクタという
nobuoka.icon 「Adopting Modern Objective-C」 によると、designated initializer じゃない initializer を convenience initializer というらしいが、convenience initializer とコンビニエンスコンストラクタは別物なのかな……?
循環参照に注意
基本的に、オブジェクトグラフは木構造になるようにする
参照渡し的なことを ARC ではライトバック渡しで実現
ARC を用いたプログラムでは C の構造体や共用体のメンバにオブジェクトを含めてはならない
構造体の内部までオーナーシップの管理ができないため
6 章 : ガーベジコレクション
ガベージコレクションは Mac OS X 10.5 Leopard 以降で利用可能 (iOS では利用できない)
Mac OS X 10.7 Lion および iOS 5 以降では ARC の利用が推奨 (= ガベージコレクションはあくまで消極的な選択子)
7 章 : 宣言プロパティ
宣言プロパティ (declared property) は、クラスというものに、メソッドとは異なる概念としてプロパティを追加するもの
8 章 : NSObject クラスとランタイムシステム
Objective-C ではオブジェクトの動的な振る舞いの実現のためにランタイムシステム (runtime system) の助けを借りる
それらの基本的な機能はルートクラスの NSObject に用意されている
methodForSelector: メソッドなどで、メソッドに対応する関数へのポインタ (IMP 型) を取得できる
関数には隠し引数 (hidden arguments) がある
第 1 引数が自分自身 (self で参照可能)、第 2 引数がセレクタ (SEL 型で、_cmd で参照可能)
クラスオブジェクトのクラスはメタクラス (metaclass)
Cocoa 環境と Cocoa Touch
Mac OS X では 10.7 Lion で 64 ビット対応に
それに先立ってランタイムシステムが大幅刷新 (Apple のドキュメントでは、モダンランタイム / レガシーランタイムと表現)
Mac OS X はプログラミングデータモデルとして ILP32 と LP64 を採用
Cocoa 環境では NSInteger 型が導入され、32 ビット環境では int 型、64 ビット環境では long 型に
9 章 Foundation フレームワークの重要なクラス
オブジェクトの変更可能性 (mutability)
バイト列からなるデータを扱う際には NSData
高速列挙 (fast enumeration) : for (obj in group) ...
URL を扱うための NSURL
10 章 カテゴリ
クラスの一部のメソッドを実現するモジュールをカテゴリという
カテゴリはもともと Smalltalk にあった概念
クラス拡張 (class extension) という仕組みもある
宣言はカテゴリに似ているが、カテゴリ名のようなものを書かない
カテゴリではインスタンス変数の追加ができないが、連想参照 (associative reference) により参照を保持できる
nobuoka.icon オブジェクトは全部辞書である、っていう JavaScript っぽさがあるな
11 章 抽象クラスとクラスクラスタ
Objective-C には、言語機能として抽象クラスを宣言する方法はない (あくまで概念となっている)
クラスクラスタ (class cluster) は、同じインターフェイスを持ち同じ機能を提供する複数のクラスの集合体
12 章 プロトコル
Objective-C のプロトコルは、もともと分散オブジェクト間の通信規約を抽象化した概念として言語に取り入れられた
Java におけるインターフェイスは、Objective-C のプロトコルを取り入れたもの
nobuoka.icon そうなんだ???
プロトコルを採用 (adopt) し、そのメソッドを全て実現しているクラスは、そのプロトコルに適合 (confirm) しているという
あるいは準拠している
非形式プロトコル (informal protocl) あるいは簡易プロトコル : メソッドの一群を NSObject のカテゴリとして宣言
実装は、それを使う側のクラスが行う
システム (フレームワーク) 側からユーザープログラム側のオブジェクトに情報を渡すときなどに使う
nobuoka.icon プロトコルを使うのじゃダメなのか???
13 章 オブジェクトのコピーと保存
Cocoa では、従来、動的に確保されるメモリの管理をゾーンと呼ばれる領域を使って行ってきた
新しいランタイムシステムでは使われない
copyWithZone: メソッドの引数として形式的に残っている
Foundation フレームワークには、複数のオブジェクトをバイト列に変換する仕組みもある
この変換を、「アーカイブする」 あるいは 「エンコードする」 という
このバイト列をアーカイブ (archive) と呼ぶ
対象のオブジェクトは NSCoding プロトコルに適合する必要
復元のために initWithCoder: というイニシャライザを用意する必要
プロパティリスト (property list) で様々な情報の表現や保存
14 章 ブロックオブジェクト
Mac OS X 10.6 と iOS 4.0 から
ブロックオブジェクト (block object) が利用可能に
Grand Central Dispatch (GCD) も
15 章 メッセージ送信のパターン
GUI アプリケーションにおいて UI イベントをうけとって処理を起動するループ : 実行ループ (run loop) あるいはイベントループ
実行ループへのアクセスには NSRunLoop クラスを用いる
NSTimer による遅延実行あるいは定期実行ができる
NSObject で定義されている -performSelector:withObject:afterDelay: メソッドによる遅延実行も可能
デリゲート (delegate)
Foundation フレームワークには、通知 (notification) と呼ばれるメッセージ送信方式がある
プログラム内の通知センタ (notification center) と呼ばれるオブジェクトが中心 (NSNotificationCenter クラス)
レスポンダチェーン (responder chain)
メッセージの転送
処理できないメッセージがオブジェクトに送られた場合、ランタイムはオブジェクトに -forwardInvocation: というメッセージを送る
デフォルトでは -doesNotRecognizeSelector: が呼ばれるが、オーバーライドすることで任意のメッセージを処理できる
NSUndoManager によるアンドゥ (undo) 機構
16 章 アプリケーションの構造
Cocoa のアプリケーションは必要なリソースが 1 つのディレクトリにまとめられている : アプリケーションバンドル (application bundle)
いくつかのファイルやディレクトリを特定の形式のディレクトリにまとめた構造を一般にバンドルという
リソースファイル
GUI 定義は Interface Builder で作られた nib ファイルに格納される
Xcode 4.2 からは Storyboard も利用できるように
言語に依らないリソースファイルの配置場所
Mac OS X の場合は Resources の直下
iOS の場合はアプリケーションバンドルの直下
言語に応じて切り替えたいリソースは 「言語名.lproj」 というディレクトリに格納
バンドル内の Info.plist はプロパティリスト
アプリケーション実行に不可欠な情報が記入されている
プログラムから見た時、それ自身が含まれているバンドルをメインバンドルという
NSBundle の mainBundle で取得可能
ユニバーサルバイナリ (universal binary)
ユニバーサルアプリケーション
ユーザーデフォルト
ローカライズ → Cocoa におけるローカライズ
Mac OS X ではモジュールの動的ロードが可能
17 章 例題 : 簡易画像ビューア
18 章 例外とエラー
Objective-C の例外
NSAssert でアサーション可能
エラーメッセージ表示用の NSError クラスがある
エラー・レスポンダチェーン
19 章 並列プログラミング
スレッド
Objective-C の並列処理
20 章 キー値コーディング
キー値コーディング (key-value coding)
キー値監視 (key-value observing)
Cocoa バインディング
付録
Core Foundation フレームワーク